package com.hucsmn.examsystem.session;

import com.hucsmn.examsystem.common.message.Token;
import com.hucsmn.examsystem.server.ExamServerException;

import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 会话状态容器。
 */
public class SessionCollection {
    public static final long DEFAULT_EXPIRE = 24 * 3600;

    private final ConcurrentMap<Token, Session> sessions = new ConcurrentHashMap<>();

    public Token login(int uid, boolean admin) throws ExamServerException {
        Token token = new Token();
        if (sessions.putIfAbsent(token, new Session(uid, admin)) != null) {
            throw new ExamServerException("failed to generate token");
        }
        return token;
    }

    public void logout(Token token) {
        sessions.remove(token);
    }

    public void clean() {
        clean(DEFAULT_EXPIRE);
    }

    public void clean(long expire) {
        if (expire == 0) {
            return;
        }
        if (expire < 0) {
            sessions.clear();
            return;
        }
        sessions.entrySet().removeIf(entry -> entry.getKey().lifetime() >= expire);
    }

    public Optional<Session> access(Token token) {
        return Optional.ofNullable(sessions.get(token));
    }

    public Session get(Token token) throws ExamServerException {
        return access(token)
                .orElseThrow(() -> new ExamServerException("bad or expired token"));
    }
}
